#define __LIBRARY__
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <linux/sem.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <linux/mm.h>

_syscall2(sem_t *,sem_open,const char *,name,unsigned int,value)
_syscall1(int,sem_wait,sem_t *,sem)
_syscall1(int,sem_post,sem_t *,sem)
_syscall1(int,sem_unlink,const char *,name)
_syscall3(int,shmget,key_t,key,size_t,size,int,shmflg);
_syscall3(void *,shmat,int,shmid,const void *,shmaddr,int,shmflg);

#define BUFSIZE 10     
#define PRODUCTS 500
#define INVAILD_NUMBER  -1 
const int key = 1190202209;
const char *full_name = "lab6full";
const char *empty_name = "lab6empty";
const char *mutex_name = "lab6mutex";
sem_t *empty, *full, *mutex;
int shmid;

void Consumer()
{
    int i,fd, count = 0;
    int *buf,*p,*q;
    buf = (int *)shmat(shmid,NULL,0);
    while (count<=PRODUCTS)
    {
        sem_wait(full);
        sem_wait(mutex);
        printf("%d: %d\n",getpid(),*buf);
        fflush(stdout);
        q = buf;
        p = buf + 1;
        *q = INVAILD_NUMBER;
        while(*p!=INVAILD_NUMBER && p< buf + BUFSIZE){
            *q = *p;
            *p = INVAILD_NUMBER;
            p++;q++;
        }
        sem_post(mutex);
        sem_post(empty);
        count++;
    }
    return;
}

int main()
{    
    shmid = shmget(key, BUFSIZE*sizeof(int),0);
    empty = sem_open(empty_name, BUFSIZE); 
    full = sem_open(full_name, 0);         
    mutex = sem_open(mutex_name, 1);     
    Consumer(); 
    sem_unlink(full_name);
    sem_unlink(empty_name);
    sem_unlink(mutex_name);
    return 0;
}
